package com.zsp.utils.security_jwt;

import com.zsp.utils.security_jwt.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Component;

@Component // 将此类标记为一个 Spring 容器的组件，表示它作为一个 Spring Bean 被加载
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    // 构造函数注入 JwtAuthenticationFilter
    // Spring 会自动将 JwtAuthenticationFilter 注入进来
    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean // 将方法 `passwordEncoder` 注册为一个 Spring Bean，供全局使用
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
        /*
         * 返回一个使用 Bcrypt 算法的 PasswordEncoder 实例。
         * BCrypt 是一种强哈希算法，适合用来加密用户密码。
         * 每次生成的加密结果都带有随机盐值，可以有效抵御彩虹表攻击。
         */
    }

    @Bean // 将方法 `securityFilterChain` 注册为一个 Spring Bean，定义应用的安全规则
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                /*
                 * 禁用 CSRF（跨站请求伪造）保护。
                 * 前后端分离项目通常通过 Token 来保护安全性，因此可以禁用 CSRF（在表单应用中常用）。
                 */

                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                /*
                 * 将会话管理设置为无状态 (Stateless)。
                 * Spring Security 不会创建 Session，也不会将用户信息存储于 Session 中。
                 * 这是因为使用了 JWT 认证，每次请求都携带 Token，因此不需要 Session。
                 */

                .and()
                .authorizeRequests()
                /*
                 * 配置基于路径的访问控制规则。
                 * 此方法用于指定哪些 URL 需要认证，哪些可以放行。
                 */

                .antMatchers("/auth/login", "/auth/register").permitAll()
                /*
                 * 对登录 (`/auth/login`) 和注册 (`/auth/register`) 接口放行，允许直接访问，无需验证。
                 * 这些接口通常是对外公开的，用于用户初始认证或创建新账号。
                 */

                .antMatchers("/public/**").permitAll()
                /*
                 * 对以 `/public/` 开头的所有请求路径放行，例如静态资源路径。
                 * 这些通常是无需保护的公开资源（如图片、CSS 文件等）。
                 */

                .anyRequest().authenticated()
                /*
                 * 对所有其他请求均需进行身份认证。
                 * 如果未携带有效 Token 或未通过认证请求，则返回 401 Unauthorized 响应。
                 */

                .and()
                .addFilterBefore(jwtAuthenticationFilter, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.class);
        /*
         * 在 Spring Security 过滤器链中，将自定义的 `JwtAuthenticationFilter` 添加到 `UsernamePasswordAuthenticationFilter` 之前。
         * JwtAuthenticationFilter 的作用：
         * - 解析请求中的 JWT Token
         * - 验证 Token 的合法性和有效性
         * - 设置当前用户的认证信息，用于后续权限控制
         */

        return http.build(); // 最终构建并返回安全配置
    }
}
